package cn.hpclub.server.plugin;

import java.util.concurrent.ConcurrentHashMap;

import org.nutz.ssdb4j.spi.SSDB;

import com.jfinal.kit.StrKit;

public class Ssdb{
    static Cache mainCache = null;
    static boolean enabled = true;
    
    private static final ConcurrentHashMap<String, Cache> cacheMap = new ConcurrentHashMap<String, Cache>();
    
    static synchronized void addCache(Cache cache) {
        if (cache == null)
            throw new IllegalArgumentException("cache can not be null");
        if (cacheMap.containsKey(cache.getName()))
            throw new IllegalArgumentException("cache already exists");
        
        cacheMap.put(cache.getName(), cache);
        if (mainCache == null)
            mainCache = cache;
    }
    
    static Cache removeCache(String cacheName) {
        return cacheMap.remove(cacheName);
    }
    
    /**
     * 提供一个设置设置主缓存 mainCache 的机会，否则第一个被初始化的 Cache 将成为 mainCache
     */
    public static void setMainCache(String cacheName) {
        if (StrKit.isBlank(cacheName))
            throw new IllegalArgumentException("cacheName can not be blank");
        cacheName = cacheName.trim();
        Cache cache = cacheMap.get(cacheName);
        if (cache == null)
            throw new IllegalArgumentException("the cache not exists: " + cacheName);
        
        Ssdb.mainCache = cache;
    }
    public static boolean enabled() {
        return enabled;
    }
    public static void setEnabled(boolean enabled) {
        Ssdb.enabled = enabled;
    }
    public static Cache use() {
        return mainCache;
    }
    
    public static Cache use(String cacheName) {
        return cacheMap.get(cacheName);
    }
    
    public static Object call(ICallback callback) {
        return call(callback, null);
    }
    
    public static Object call(ICallback callback, String cacheName) {
        Cache cache = (cacheName != null ? use(cacheName) : use()); 
        SSDB ssdb = cache.getThreadLocalSsdb();
        boolean notThreadLocalSsdb = (ssdb == null);
        if (notThreadLocalSsdb) {
            ssdb = cache.ssdb;
            cache.setThreadLocalSsdb(ssdb);
        }
        try {
            return callback.call(cache);
        }
        finally {
            if (notThreadLocalSsdb) {
                cache.removeThreadLocalSsdb();
                //ssdb.close();
            }
        }
    }
}
